<?php
/**
 * NOTICE OF LICENSE
 *
 * This source file is subject to the  Academic Free License (AFL 3.0)
 * that is available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to support@zprofess.com so we can send you a copy immediately.
 *
 * @category   	Prestashop module
 * @package		Review & Rating Synthesis
 * @version 	1.0.2
 * @author 		Rukan <rukanhitokiri@zprofess.com>
 * @copyright   Copyright (c) 2012 ZPROFESS. (http://www.zprofess.com)
 * @license    	http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */

include_once(dirname(__FILE__).'/classes/ZProductCriterion.php');
include_once(dirname(__FILE__).'/classes/ZProductList.php');

class AdminZProductCriterion extends AdminTab
{
	/**
	 * @var array
	 */
	private $_criterionType;
	
	/**
	 * @var string table name
	 */
	public $tableProduct = 'product';
	
	/** 
	 * @var object ProductList instance  
	 */
	private $_productList;
	
	public function __construct()
	{
		global $cookie;
	 	$this->table = 'zproduct_criterion';
	 	$this->className = 'ZProductCriterion';
	 	$this->lang = true;
	 	$this->edit = true;
		$this->delete = true;
	
		$this->_criterionType = ZProductCriterion::getCriterionTypes();
		$this->fieldsDisplay = array(
			'id_zproduct_criterion'      => array('width' => 60,  'title' => $this->l('ID'), 'align' => 'center'),
			'name' 	  					 => array('width' => 250, 'title' => $this->l('Criterion')),
	 		'id_zproduct_criterion_type' => array('width' => 250, 'title' => $this->l('Type'), 'type' => 'select', 'select' => $this->_criterionType, 'filter_key' => 'a!id_zproduct_criterion_type', 'callback' => 'displayCriterionType'),
	 	    'active' 					 => array('width' => 90,  'title' => $this->l('Enabled'), 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false));
	 	
		$this->_productList = new ZProductList();
		
		parent::__construct();
	}
	
    /**
	 * Manage page processing
	 * @view AdminTab::postProcess()
	 *
	 * @global string $currentIndex Current URL in order to keep current Tab
	 */
	public function postProcess()
	{
		global $currentIndex, $cookie;
		
		//echo '<pre>';var_dump($_POST);die();
		
		// set token
		$token = Tools::getValue('token') ? Tools::getValue('token') : $this->token;
		
		/* Cancel all filters for this tab */
		if (isset($_POST['submitReset'.$this->tableProduct])) {
			if(isset($_POST['id_zproduct_criterion']))
				$id_zproduct_criterion = $_POST['id_zproduct_criterion'];
			$this->_productList->postProcess();
			if (isset($id_zproduct_criterion)) {
				Tools::redirectAdmin($currentIndex.'&id_zproduct_criterion='.(int)$id_zproduct_criterion.'&updatezproduct_criterion&submit_reset&token='.$token);
			} else {
				Tools::redirectAdmin($currentIndex.'&addzproduct_criterion&submit_reset&token='.$token);
			}
		} 
		/* Manage list filtering */
		elseif (Tools::isSubmit('submitFilter'.$this->tableProduct) OR $cookie->{'submitFilter'.$this->tableProduct} !== false) {
			
			if(isset($_POST['pagination'])) {
				$cookie->{$this->tableProduct.'_pagination'} = Tools::getValue('pagination');
			}
			$this->_productList->postProcess();
			if (Tools::isSubmit('submitFilter'.$this->tableProduct) && isset($_POST['submitFilter'])) {
				if (isset($_POST['id_zproduct_criterion'])) {
					Tools::redirectAdmin($currentIndex.'&id_zproduct_criterion='.(int)Tools::getValue('id_zproduct_criterion').'&updatezproduct_criterion&submit_filter&token='.$token);
				} else {
					Tools::redirectAdmin($currentIndex.'&addzproduct_criterion&submit_filter&token='.$token);
				}
			}
		}
		
		if (Tools::getValue('submitAdd'.$this->table) AND !isset($_POST['x']) AND !isset($_POST['y'])) {
			$this->validateRules();
			if (!sizeof($this->_errors)) {
				$id = (int)Tools::getValue('id_'.$this->table);
				/* Object update */ 
				if (isset($id) AND !empty($id)) {
					if ($this->tabAccess['edit'] === '1') {
						$object = new $this->className($id);
						if (Validate::isLoadedObject($object)) {

							// Begin Zpro: Updating criterion's category, criterion's products
							if(ZProductCriterion::CRITERION_TYPE_SOME_CATEGORIES == Tools::getValue('id_zproduct_criterion_type')) {
								$categoryList = Tools::getValue('categoryBox');
								if (!is_array($categoryList) OR sizeof($categoryList) == 0)
									$this->_errors[] = Tools::displayError('Criterion must be in at least one category.');
								if (!sizeof($this->_errors)) {
									$object->addCategories($categoryList);
								}
							} 
							elseif(ZProductCriterion::CRITERION_TYPE_SOME_PRODUCTS == Tools::getValue('id_zproduct_criterion_type')) {
								$productList = Tools::getValue('productBox');
								if (!is_array($productList) OR sizeof($productList) == 0)
									$this->_errors[] = Tools::displayError('Criterion must be in at least one product.');
								if (!sizeof($this->_errors)) {
									$object->addProducts($productList);
								}
							}
							// End Zpro: Updating criterion's category, criterion's products

						} else
							$this->_errors[] = Tools::displayError('An error occurred while updating object.').' <b>'.$this->table.'</b> '.Tools::displayError('(cannot load object)');
					} else
						$this->_errors[] = Tools::displayError('You do not have permission to edit here.');
				/* Object creation */
				} else {
					if ($this->tabAccess['add'] === '1') {
						
						// Begin Zpro: Add associated categories, products
						if(ZProductCriterion::CRITERION_TYPE_SOME_CATEGORIES == Tools::getValue('id_zproduct_criterion_type')) {
							$categoryList = Tools::getValue('categoryBox');
							if (!is_array($categoryList) OR sizeof($categoryList) == 0)
								$this->_errors[] = Tools::displayError('Criterion must be in at least one category.');
						} 
						elseif(ZProductCriterion::CRITERION_TYPE_SOME_PRODUCTS == Tools::getValue('id_zproduct_criterion_type')) {
							$productList = Tools::getValue('productBox');
							if (!is_array($productList) OR sizeof($productList) == 0)
								$this->_errors[] = Tools::displayError('Criterion must be in at least one product.');
						}
						// End Zpro: Add associated categories, products
						
						if (!sizeof($this->_errors)) {
							$object = new $this->className();
							$this->copyFromPost($object, $this->table);
							if (!$object->add())
								$this->_errors[] = Tools::displayError('An error occurred while creating object.').' <b>'.$this->table.' ('.mysql_error().')</b>';
							elseif (($_POST[$this->identifier] = $object->id /* voluntary */) AND $this->postImage($object->id) AND !sizeof($this->_errors) AND $this->_redirect) {
								
								// Begin Zpro: Add associated categories, products
								if(ZProductCriterion::CRITERION_TYPE_SOME_CATEGORIES == Tools::getValue('id_zproduct_criterion_type')) {
									$object->addCategories($categoryList);
								} 
								elseif(ZProductCriterion::CRITERION_TYPE_SOME_PRODUCTS == Tools::getValue('id_zproduct_criterion_type')) {
									$object->addProducts($productList);
								}
								// End Zpro: Add associated categories, products
								
								$parent_id = (int)(Tools::getValue('id_parent', 1));
								// Save and stay on same form
								if (Tools::isSubmit('submitAdd'.$this->table.'AndStay'))
									Tools::redirectAdmin($currentIndex.'&'.$this->identifier.'='.$object->id.'&conf=3&update'.$this->table.'&token='.$this->token);
								// Save and back to parent
								if (Tools::isSubmit('submitAdd'.$this->table.'AndBackToParent'))
									Tools::redirectAdmin($currentIndex.'&'.$this->identifier.'='.$parent_id.'&conf=3&token='.$this->token);
								// Default behavior (save and back)
								Tools::redirectAdmin($currentIndex.($parent_id ? '&'.$this->identifier.'='.$object->id : '').'&conf=3&token='.$this->token);
							}
						}
					} else
						$this->_errors[] = Tools::displayError('You do not have permission to add here.');	
				}
			}
		}
		/* Delete object */
		elseif (isset($_GET['delete'.$this->table]))
		{
			if ($this->tabAccess['delete'] === '1')
			{
				if (Validate::isLoadedObject($object = $this->loadObject()) AND isset($this->fieldImageSettings))
				{
					// check if request at least one object with noZeroObject
					if (isset($object->noZeroObject) AND sizeof(call_user_func(array($this->className, $object->noZeroObject))) <= 1)
						$this->_errors[] = Tools::displayError('You need at least one object.').' <b>'.$this->table.'</b><br />'.Tools::displayError('You cannot delete all of the items.');
					else
					{
						// Begin Zpro: Delete associated categories, products
						$object->deleteAssociated();
						// Begin Zpro: Delete associated categories, products

						if ($this->deleted)
						{
							$object->deleteImage();
							$object->deleted = 1;
							if ($object->update())
								Tools::redirectAdmin($currentIndex.'&conf=1&token='.$token);
						}
						elseif ($object->delete())
							Tools::redirectAdmin($currentIndex.'&conf=1&token='.$token);
						$this->_errors[] = Tools::displayError('An error occurred during deletion.');
					}
				}
				else
					$this->_errors[] = Tools::displayError('An error occurred while deleting object.').' <b>'.$this->table.'</b> '.Tools::displayError('(cannot load object)');
			}
			else
				$this->_errors[] = Tools::displayError('You do not have permission to delete here.');
		}
		/* Delete multiple objects */
		elseif (Tools::getValue('submitDel'.$this->table))
		{
			if ($this->tabAccess['delete'] === '1')
			{
				if (isset($_POST[$this->table.'Box']))
				{
					$object = new $this->className();
					if (isset($object->noZeroObject) AND
						// Check if all object will be deleted
						(sizeof(call_user_func(array($this->className, $object->noZeroObject))) <= 1 OR sizeof($_POST[$this->table.'Box']) == sizeof(call_user_func(array($this->className, $object->noZeroObject)))))
						$this->_errors[] = Tools::displayError('You need at least one object.').' <b>'.$this->table.'</b><br />'.Tools::displayError('You cannot delete all of the items.');
					else
					{						
						$result = true;
						
						// Begin Zpro: Delete associated categories, products
						foreach(Tools::getValue($this->table.'Box') as $id) {
							$result = $result AND $object->deleteAssociated($id);
						}
						// Begin Zpro: Delete associated categories, products
						
						if ($this->deleted)
						{
							foreach(Tools::getValue($this->table.'Box') as $id)
							{
								$toDelete = new $this->className($id);
								$toDelete->deleted = 1;
								$result = $result AND $toDelete->update();
							}
						}
						else {
							$result = $object->deleteSelection(Tools::getValue($this->table.'Box'));
						}

						if ($result)
							Tools::redirectAdmin($currentIndex.'&conf=2&token='.$token);
						$this->_errors[] = Tools::displayError('An error occurred while deleting selection.');
					}
				}
				else
					$this->_errors[] = Tools::displayError('You must select at least one element to delete.');
			}
			else
				$this->_errors[] = Tools::displayError('You do not have permission to delete here.');
		}
		
		if (!isset($_POST['x']) AND !isset($_POST['y'])) {
			parent::postProcess();
		}
	}
	
	/**
	 * render Javascript
	 * 
	 * @return string
	 */
	private function _renderJS()
	{
		return
		'<script type="text/javascript">
			$(document).ready(function(){
				$(\'#id_zproduct_criterion_type\').change(function() {
					id_zproduct_criterion_type = $("#id_zproduct_criterion_type").val();
					if (id_zproduct_criterion_type == 2) {
						$("#contains_criterion_product").fadeOut();
						$("#contains_criterion_category").fadeIn();
					} else if (id_zproduct_criterion_type == 3) {
						$("#contains_criterion_category").fadeOut();
						$("#contains_criterion_product").fadeIn();
					} else {
						$("#contains_criterion_product").fadeOut();
						$("#contains_criterion_category").fadeOut();
					}
				});
				
			}); 	
		</script>';
	}
	
	/**
	 * Display form
	 * @view AdminTab::displayForm()
	 *
	 * @global string $currentIndex Current URL in order to keep current Tab
	 */
	public function displayForm($isMainTab = true)
	{
		global $currentIndex, $cookie;
		parent::displayForm();
		
		if (!($obj = $this->loadObject(true)))
			return;
			
		echo $this->_renderJS().
		'<form id="formCriterion" action="'.$currentIndex.'&submitAdd'.$this->table.'=1&token='.$this->token.'" method="post">
		'.($obj->id ? '<input type="hidden" name="id_'.$this->table.'" value="'.$obj->id.'" />' : '').'
			<fieldset><legend><img src="../img/admin/contact.gif" />'.$this->l('Add a new criterion').'</legend>
				<label>'.$this->l('Name:').'</label>
				<div class="margin-form translatable">';
		foreach ($this->_languages as $language)
			echo 	'<div id="name_'.$language['id_lang'].'" style="display: '.($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none').'; float: left;">
						<input type="text" style="width: 260px" name="name_'.$language['id_lang'].'" id="name_'.$language['id_lang'].'" value="'.htmlentities($this->getFieldValue($obj, 'name', (int)($language['id_lang'])), ENT_COMPAT, 'UTF-8').'" /><sup> *</sup>
						<span class="hint" name="help_box">'.$this->l('Invalid characters:').' <>;=#{}<span class="hint-pointer">&nbsp;</span></span>
					</div>';
					$this->displayFlags($this->_languages, $this->_defaultFormLanguage, 'name', 'name');
		echo 		'<p class="clear">'.$this->l('You can define several criteria to help your customers during their rating (e.g., efficiency, lightness, design)').'</p>
				</div>
				
				<label>'.$this->l('Active:').'</label>
				<div class="margin-form">
					<input type="radio" name="active" id="active_on" value="1" '.($this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
					<label class="t" for="active_on"><img src="../img/admin/enabled.gif" alt="'.$this->l('Enabled').'" title="'.$this->l('Enabled').'" /></label>
					<input type="radio" name="active" id="active_off" value="0" '.(!$this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
					<label class="t" for="active_off"><img src="../img/admin/disabled.gif" alt="'.$this->l('Disabled').'" title="'.$this->l('Disabled').'" /></label>
					<p class="clear">'.$this->l('The criterion will be active or not').'</p>
				</div>';
		
		echo	'<label>'.$this->l('Apply to:').'</label>
				<div class="margin-form">
					<select id="id_zproduct_criterion_type" name="id_zproduct_criterion_type">';
		$selectedCriterionType = $this->getFieldValue($obj, 'id_zproduct_criterion_type');
		if(isset($_GET['submit_reset']) OR isset($_GET['submit_filter'])) {
			$selectedCriterionType = 3;
		}
		foreach ($this->_criterionType as $k => $type)
			echo		'<option value="'.$k.'" '.($k == $selectedCriterionType ? 'selected="selected"' : '').'>'.$type.'</option>';
		echo		'</select>
					<p class="clear">'.$this->l('Criterions scope').'</p>
				</div>';

		/*Build a categories tree*/
		echo 	'<div id="contains_criterion_category" '.(($selectedCriterionType != ZProductCriterion::CRITERION_TYPE_SOME_CATEGORIES) ? 'style="display:none;"' : '').'>
				<label>'.$this->l('Categories:').'</label>
				<div class="margin-form">
					<table cellspacing="0" cellpadding="0" class="table" style="width: 600px;">
						<tr>
							<th><input type="checkbox" name="checkme" class="noborder" onclick="checkDelBoxes(this.form, \'categoryBox[]\', this.checked)" /></th>
							<th>'.$this->l('ID').'</th>
							<th>'.$this->l('Name').'</th>
						</tr>';
		$done = array(); 
		$index = array();
		$indexedCategories = $obj->getCategoriesId();
		$categories = Category::getCategories((int)$cookie->id_lang); /*Return only active categories*/
		$this->recurseCategoryForInclude((int)Tools::getValue($this->identifier), $indexedCategories, $categories, $categories[0][1], 1, $obj->id);
		echo 		'</table>
					<p style="padding:0px; margin:0px 0px 10px 0px;">'.$this->l('Mark all checkbox(es) of categories to which the criterion is to be applied').'<sup> *</sup></p>
				</div>';
		echo 	'</div>';
		
		echo 	'<div id="contains_criterion_product" '.(($selectedCriterionType != ZProductCriterion::CRITERION_TYPE_SOME_PRODUCTS) ? 'style="display:none;"' : '').'>';
					$productsId = $obj->getProductsId();
					$this->_productList->display($this->token, $productsId);
		echo	'</div>
				<div class="clear">&nbsp;</div>';
		
		echo	'<div class="margin-form">
					<input type="submit" value="'.(Tools::getValue('id_zproduct_criterion') ? $this->l('Modify this criterion') : $this->l('Add this criterion')).'" name="submitAdd'.$this->table.'" class="button" />
				</div>
				<div class="small"><sup>*</sup> '.$this->l('Required field').'</div>
			</fieldset>
		</form>
		<p class="clear"></p>';
	}
	
	/**
	 * Build a categories tree
	 *
	 * @param array $indexedCategories Array with categories where product is indexed (in order to check checkbox)
	 * @param array $categories Categories to list
	 * @param array $current Current category
	 * @param integer $id_category Current category id
	 */
	public static function recurseCategoryForInclude($id_obj, $indexedCategories, $categories, $current, $id_category = 1, $id_category_default = NULL, $has_suite = array())
	{
		global $done;
		static $irow;

		if (!isset($done[$current['infos']['id_parent']]))
			$done[$current['infos']['id_parent']] = 0;
		$done[$current['infos']['id_parent']] += 1;

		$todo = sizeof($categories[$current['infos']['id_parent']]);
		$doneC = $done[$current['infos']['id_parent']];

		$level = $current['infos']['level_depth'] + 1;

		echo '
		<tr class="'.($irow++ % 2 ? 'alt_row' : '').'">
			<td>
				<input type="checkbox" name="categoryBox[]" class="categoryBox'.($id_category_default == $id_category ? ' id_category_default' : '').'" id="categoryBox_'.$id_category.'" value="'.$id_category.'"'.((in_array($id_category, $indexedCategories) OR ((int)(Tools::getValue('id_category')) == $id_category AND !(int)($id_obj))) ? ' checked="checked"' : '').' />
			</td>
			<td>
				'.$id_category.'
			</td>
			<td>';
			for ($i = 2; $i < $level; $i++)
				echo '<img src="../img/admin/lvl_'.$has_suite[$i - 2].'.gif" alt="" style="vertical-align: middle;"/>';
			echo '<img src="../img/admin/'.($level == 1 ? 'lv1.gif' : 'lv2_'.($todo == $doneC ? 'f' : 'b').'.gif').'" alt="" style="vertical-align: middle;"/> &nbsp;
			<label for="categoryBox_'.$id_category.'" class="t">'.stripslashes($current['infos']['name']).'</label></td>
		</tr>';

		if ($level > 1)
			$has_suite[] = ($todo == $doneC ? 0 : 1);
		if (isset($categories[$id_category]))
			foreach ($categories[$id_category] AS $key => $row)
				if ($key != 'infos')
					self::recurseCategoryForInclude($id_obj, $indexedCategories, $categories, $categories[$id_category][$key], $key, $id_category_default, $has_suite);
	}
	
	/**
	 * Close list table and submit button
	 */
	public function displayListFooter($token = NULL)
	{
		parent::displayListFooter($token = NULL);
		
		global $currentIndex, $cookie;

		echo '
			<div style="float:left;border:0;width:640px;">
				<div style="background-color:#EFEFEF;float:left;margin:0 10px 10px 0;width:300px;border:1px solid #CFCFCF" >
					<h3 style="overflow:hidden;line-height:25px;color:#812143;height:25px;margin:0;">&nbsp;Support</h3>
					<p style="overflow:hidden;line-height:15px;height:45px;margin:0;padding:0 5px;">If a technical problem occurs on this website. Please <a href="http://www.zprofess.com" target="_blank" style="text-decoration:underline;">contact us</a></p>
					<h3 style="padding:0 5px;margin:0;height:23px;line-height:23px;background-color:#DEDEDE"></h3> 
				</div>
				
				<div style="background-color:#EFEFEF;float:left;margin:0 10px 10px 0;width:300px;border:1px solid #CFCFCF" >
					<h3 style="overflow:hidden;line-height:25px;color:#812143;height:25px;margin:0;">&nbsp;Customer service</h3>
					<p style="overflow:hidden;line-height:15px;height:45px;margin:0;padding:0 5px;">For any question about a product, an order. Please <a href="http://www.zprofess.com" target="_blank" style="text-decoration:underline;">contact us</a></p>
					<h3 style="padding:0 5px;margin:0;height:23px;line-height:23px;background-color:#DEDEDE"></h3> 
				</div>
			</div>';
		
		$params = array(
			$this->l('Average rating') 			=> $rating = Db::getInstance()->getValue('SELECT ROUND(AVG(rating), 2) FROM '._DB_PREFIX_.'zproduct_review'),
			$this->l('Total customer reviews') 	=> $all = Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'zproduct_review'),
			$this->l('Reviews pending') 		=> $pending = Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'zproduct_review WHERE status = 1'),
			$this->l('Reviews Accept') 			=> $accept = Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'zproduct_review WHERE status = 2'),
			$this->l('Reviews Cancel') 			=> $all - ($accept + $pending));

		echo '<div style="float:right;padding 0px;border:1px solid #CFCFCF;width:280px;">
				<h3 class="button" style="margin:0;line-height:23px;height:23px;border:0;padding:0 5px;">'.$this->l('Review & Rating').' : '.$this->l('Statistics').'</h3>
				<table cellspacing="1" class="table" style="border-collapse:separate;width:280px;border:0">';
		$count = 0;
		foreach ($params as $key => $val)
			echo '<tr '.(++$count % 2 == 0 ? 'class="alt_row"' : '').'><td>'.$key.'</td><td style="color:green;font-weight:bold;">'.$val.'</td></tr>';
		echo '	</table>
			</div><p class="clear">&nbsp;</p>';
	}
}
